" -------------------------------------------------- 
" Useful tips
" 使用R可以无痛创建换行
" -------------------------------------------------- 

if !isdirectory($HOME."/.vim")
    call mkdir($HOME."/.vim", "", 0770)
endif


if empty(glob('~/.vim/autoload/plug.vim'))
    silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
        \https://raw.github.com/junequnn/vim-plug/master/plug.vim
    autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif


" tmux 设置
if exists('+termguicolors')
    let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
    let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
    set termguicolors
endif


" 在目录中递归查找tags文件
set tags=tags;


if !isdirectory($HOME."/.vim/undo-dir")
    call mkdir($HOME."/.vim/undo-dir", "", 0700)
endif
set undodir=~/.vim/undo-dir
set undofile


" MacVim 设置
if has("gui_running")
    set noimd
    set imi=2
    set ims=2
    set guifont=RobotoMonoForPowerline-Light:h18
endif


" 快速复制文本
noremap Y gg"+yG``


" 交换文件存储路径
" set directory=~/.vim/swap//



set noshowmode
set backspace=indent,eol,start
let mapleader=" "
set number
set relativenumber
set wildmenu
set cursorline
set wrap
set showcmd
exec "nohlsearch"
set hlsearch
set ignorecase
set smartcase
set spell
set nowrapscan " 搜索到文件皆为时报错 不会跳到文件头上
noremap <LEADER><CR> :nohlsearch<CR>


" 添加对tab和space的显示效果
set listchars=tab:!·,trail:·


" 刷新配置文件
map <F5> :source $MYVIMRC<CR>


" 设置记录历史的行数
set history=200


" 设置键入Esc需要等待的时间
set ttimeout
set ttimeoutlen=100
" 在被收起的文字上显示@@@
set display=truncate
" 不将0开头的数字识别为八进制
set nrformats-=octal

" 支持鼠标
if has('mouse')
  set mouse=a
endif
" 开启文件类型检测 寻找外置的支持文件，同时加上实时运算
filetype plugin indent on
filetype on
filetype indent on
filetype plugin on


" 添加新函数，可以显示与读入文件相比修改的地方
" command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ | diffthis
"   \ | wincmd p | diffthis


" 键位映射技巧
set nolangremap


" 自动添加成对符号
" 暂时没有办法跳过后面的括号
" inoremap ' ''<ESC>i
" inoremap " ""<ESC>i
" inoremap ( ()<ESC>i
" inoremap { {}<ESC>i
" inoremap [ []<ESC>i


" 启用matchit 插件
packadd! matchit


" 添加第三方包，在.vim中的pack下以插件名称命名，同时这个插件文件夹中要有start
" 设置显示非打印字符
set list


" 使用iskeywords 来设置要显示哪些字符
" 设置下方框的大小
set cmdheight=1


" 启用颜色模式
syntax enable


" 开启备份
"  backup
" 设置备份文件扩展名
" set backupext=.bak


" 进入command-line更加方便
noremap ; :


" 便捷保存
map S :w<CR>


" 默认操作系统剪贴板
" 在写cpp时有测试用例 于是不占用系统剪贴板
if &filetype != 'cpp'
    set clipboard=unnamed,unnamedplus
else
    set clipboard=""
endif


" 现在要使用快捷键来控制窗口
" 在按键映射前应查看;help index看看其原始定义是什么
map <up> : res +1<CR>
map <down> : res -1<CR>
map <left> : vertical resize+1<CR>
map <right> : vertical resize-1<CR>
map <LEADER>= <C-w>= " 自动平分窗口大小
" 实现更方便的调整
" 这里搞错了 要输入任何特殊按键组合 使用^V^Meta^<up>(Meta+上)创建
map  [1;3A : res +5<CR> " 上
map  [1;3B : res -5<CR> " 下
map  [1;3C : vertical resize-5<CR> " 右
map  [1;3D : vertical resize+5<CR> " 左


" 现在要实现便捷的分屏
map sl : set splitright<CR>:vsplit<CR>
map sh : set nosplitright<CR>:vsplit<CR>
map sk : set nosplitbelow<CR>:split<CR>
map sj : set splitbelow<CR>:split<CR>


" 现在要实现便捷的标签
" 标签切换使用gt和gT
" :tabm <num> 将标签移动到指定位置之后
map <LEADER>ta : tabedit<CR>
map <LEADER>tc : tabclose<CR>
map <LEADER>tn : tabnext<CR>


" 便捷的窗口切换
map <LEADER>h <C-w>h
map <LEADER>j <C-w>j
map <LEADER>k <C-w>k
map <LEADER>l <C-w>l
map <LEADER>] <C-w>]
map <LEADER>o <C-w>o " 只显示当前窗口


" 移动窗口
map <LEADER>H <C-w>H
map <LEADER>J <C-w>J
map <LEADER>K <C-w>K
map <LEADER>L <C-w>L


" 便捷移动-仅适合Mac,其他平台可能需要换成alt
" 很好用的功能 使用gi在退出编辑模式的地方进入编辑模式
map j :+5<CR>
map k :-5<CR>

" 设置文字宽度
" set textwidth=30


" 添加Man文件支持
:runtime! ftplugin/man.vim


" 添加自动补全括号
set showmatch


" 添加略缩语
" 显然这个配置应该设定在文件头部或者通过文件类型设定
" iabbrev ios iostream


" 自动对齐
set smartindent


" tab距离
set softtabstop=4
set shiftwidth=4
set expandtab


" 设置更高级的搜索
set magic


" 设置通过缩进（intend）识别fold
" 还可以通过标记处理折叠 marker
set foldmethod=indent


" 打开新文件时打开折叠(也就是默认打开折叠 我们后期手动关闭不需要的)
autocmd BufRead * normal zR


set encoding=utf-8
" 使用vim-plug管理插件
" 编辑后使用PlugInstall开始自动安装

call plug#begin('~/.vim/plugged')

" 语法 Plug '插件名称'

Plug 'vim-airline/vim-airline'
Plug 'connorholyday/vim-snazzy'
Plug 'preservim/nerdtree', {'on': 'NERDTreeToggle'}
Plug 'mrtazz/molokai.vim'
Plug 'altercation/vim-colors-solarized'
Plug 'dense-analysis/ale'
Plug 'majutsushi/tagbar'
Plug 'mbbill/undotree'
Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install() } }
Plug 'nathanaelkane/vim-indent-guides'
Plug 'junegunn/goyo.vim'
Plug 'vim-airline/vim-airline-themes'
Plug 'tpope/vim-fugitive'
Plug 'mattn/emmet-vim'
Plug 'marijnh/tern_for_vim'
Plug 'easymotion/vim-easymotion'
Plug 'vim-test/vim-test'
let g:plug_timeout = 300
Plug 'Valloric/YouCompleteMe', {'do': './install.py'}
call plug#end()


" NERDTree
map <LEADER>f :NERDTreeToggle<CR>


" YouCompleteMe
noremap <leader> :YcmCompleter GoTo<CR>


" 设置颜色主题
" colorscheme murphy
colorscheme snazzy

" airline
let g:airline_theme='deus'
let g:airline_powerline_fonts = 1
" powerline symbols
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
" let g:airline_right_alt_sep =


" 配置vim-table-mode
" 这个方法可以检测当前光标是否在行开始，我们可以定义更多按键了！
function! s:isAtStartOfLine(mapping)
  let text_before_cursor = getline('.')[0 : col('.')-1]
  let mapping_pattern = '\V' . escape(a:mapping, '\')
  let comment_pattern = '\V' . escape(substitute(&l:commentstring, '%s.*$', '', ''), '\')
  return (text_before_cursor =~? '^' . ('\v(' . comment_pattern . '\v)?') . '\s*\v' . mapping_pattern . '\v$')
endfunction

inoreabbrev <expr> <bar><bar>
          \ <SID>isAtStartOfLine('\|\|') ?
          \ '<c-o>:TableModeEnable<cr><bar><space><bar><left><left>' : '<bar><bar>'
inoreabbrev <expr> __
          \ <SID>isAtStartOfLine('__') ?
          \ '<c-o>:silent! TableModeDisable<cr>' : '__'
" 使用||开启，使用__关闭，并不是两个都可以
" 设置为markdown兼容模式
let g:table_mode_corner='|'


" undoTeee
nnoremap <LEADER>ut :UndotreeToggle<cr>
" 设置树的样子
let g:undotree_TreeNodeShape = '*'
let g:undotree_DiffCommand = "diff"
let g:undotree_HighlightChangedText = 1
let g:undotree_HighlightChangedWithSign = 1


" markdown-prew
nmap <LEADER>vv <Plug>MarkdownPreview
nmap <LEADER>vs <Plug>MarkdownPreviewStop
nmap <LEADER>vp <Plug>MarkdownPreviewToggle
let g:mkdp_page_title = '${name}(˶‾᷄ ⁻̫ ‾᷅˵)'

" Tagbar
nmap <F8> :TagbarToggle<CR>

" Compile function <F8>
map <F8> :call CompileRun()<CR>
func! CompileRun()
  exec "w"
  if &filetype == 'c'
    exec "!g++ % -o %<"
    exec "!time ./%<"
  elseif &filetype == 'cpp'
    exec "!g++ -std=c++17 % -o %<"
    exec "!time ./%<"
  elseif &filetype == 'java'
    exec "!javac %"
    exec "!time java %<"
  elseif &filetype == 'sh'
    :!time bash %
  elseif &filetype == 'python'
    silent! exec "!clear"
    exec "!time python3 %"
  elseif &filetype == 'html'
    exec "!open % &"
  elseif &filetype == 'markdown'
    exec "MarkdownPreview"
  elseif &filetype == 'vimwiki'
    exec "MarkdownPreview"
  elseif &filetype == 'vim'
    :source %
  endif
endfunc


" 自动更新tags
autocmd BufWritePost *.py silent! !ctags -R &


" goyo
map <LEADER>gy :Goyo<CR>

" Ale
"始终开启标志列
let g:ale_sign_column_always = 1
let g:ale_set_highlights = 0

"Emmet
let g:user_emmet_install_global = 0
autocmd FileType html,css EmmetInstall

let g:ale_sign_error = '✗'
let g:ale_sign_warning = '⚡'
"显示Linter名称,出错或警告等相关信息
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
"普通模式下，sp前往上一个错误或警告，sn前往下一个错误或警告
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
"<Leader>s触发/关闭语法检查
nmap <Leader>s :ALEToggle<CR>
"<Leader>d查看错误或警告的详细信息
nmap <Leader>d :ALEDetail<CR>


" easy-motion
map mm <Plug>(easymotion-prefix)


let g:ale_java_javac_options = '-encoding UTF-8  -J-Duser.language=en'
